﻿using Newtonsoft.Json;
using System;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.International.Converters.PinYinConverter;
using System.Linq;
using System.Collections.Generic;

namespace Spark.Utility
{
    public static class StringExtensions
    {
        #region MD5

        public static string EncryptMD5(this string input)
        {
            using (MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider())
            {
                return BitConverter.ToString(provider.ComputeHash(Encoding.UTF8.GetBytes(input))).Replace("-", string.Empty).ToLower();
            }
        }

        public static string EncryptShortMD5(this string input)
        {
            string Md5string = EncryptMD5(input);

            return Md5string.Substring(8, 16);
        }

        public static bool ValidateMD5(this string input, string encryptedValue)
        {
            if (string.IsNullOrEmpty(input))
            {
                return false;
            }
            if (encryptedValue.Length == 16)
            {
                return input.EncryptShortMD5().Equals(encryptedValue);
            }
            else
            {
                return input.EncryptMD5().Equals(encryptedValue);
            }
        }

        #endregion MD5

        #region JSON序列化和反序列化

        public static T FromJson<T>(this string str)
        {
            return JsonConvert.DeserializeObject<T>(str);
        }

        public static string ToJson<T>(this T obj)
        {
            return JsonConvert.SerializeObject(obj, new JsonSerializerSettings()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            });
        }

        #endregion JSON序列化和反序列化

        public static long ToInt64(this string input)
        {
            return Convert.ToInt64(input);
        }

        /// <summary>
        /// 根据GUID获取19位的唯一数字序列
        /// </summary>
        /// <returns></returns>
        public static long GuidToLongID(this Guid input)
        {
            byte[] buffer = input.ToByteArray();
            return BitConverter.ToInt64(buffer, 0);
        }

        public static bool ValidateMobile(this string input)
        {
            string pattern = "^((1[358][0-9])|(14[57])|(17[0678])|(19[7]))\\d{8}$";
            return Regex.Match(input, pattern).Success;
        }

        public static bool StringCompare(this string source, string value, bool ignoreCase = true)
        {
            if (ignoreCase)
            {
                if (source.ToLower() == value.ToLower())
                    return true;
                else
                    return false;
            }
            else
            {
                if (source == value)
                    return true;
                else
                    return false;
            }
        }

        /// <summary>
        /// 汉字转化为拼音
        /// </summary>
        /// <param name="str">汉字</param>
        /// <returns>全拼</returns>
        public static string GetPinyin(this string str)
        {
            string r = string.Empty;
            foreach (char obj in str)
            {
                try
                {
                    ChineseChar chineseChar = new ChineseChar(obj);
                    string t = chineseChar.Pinyins[0].ToString();
                    r += t.Substring(0, t.Length - 1);
                }
                catch
                {
                    r += obj.ToString();
                }
            }

            return r;
        }

        /// <summary>
        /// 汉字转化为拼音首字母
        /// </summary>
        /// <param name="str">汉字</param>
        /// <returns>首字母</returns>
        public static string GetFirstPinyin(this string str)
        {
            string r = string.Empty;
            foreach (char obj in str)
            {
                try
                {
                    ChineseChar chineseChar = new ChineseChar(obj);
                    string t = chineseChar.Pinyins[0].ToString();
                    r += t.Substring(0, 1);
                }
                catch
                {
                    r += obj.ToString();
                }
            }

            return r;
        }

        /// <summary>
        /// 汉字转化为拼音首字母
        /// </summary>
        /// <param name="str">汉字</param>
        /// <returns>首字母</returns>
        public static string GetFirstLetter(this string str)
        {
            if (!string.IsNullOrWhiteSpace(str))
            {
                try
                {
                    ChineseChar chineseChar = new ChineseChar(str[0]);
                    return chineseChar.Pinyins[0].Substring(0, 1);
                }
                catch
                {
                    return "";
                }
            }
            return "";
        }

        public static int[] IndexOfMany(this string self, string substr)
        {
            var ret = new List<int>();
            var ch1 = self.ToCharArray();
            var ch2 = substr.ToCharArray();
            for (var i = 0; i <= ch1.Length - ch2.Length; i++)
            {
                var flag = true;
                for (var j = 0; j < ch2.Length; i++)
                {
                    if (ch1[i + j] != ch2[j])
                    {
                        flag = false;
                        break;
                    }
                }
                if (flag)
                    ret.Add(i);
            }
            return ret.ToArray();
        }

        public static int CountSubString(this string self, string substr)
        {
            return self.IndexOfMany(substr).Count();
        }

        public static string PopFrontMatch(this string self, string str)
        {
            if (str.Length > self.Length)
                return self;
            else if (self.IndexOf(str) == 0)
                return self.Substring(str.Length);
            else
                return self;
        }

        public static string PopBackMatch(this string self, string str)
        {
            if (str.Length > self.Length)
                return self;
            else if (self.LastIndexOf(str) == self.Length - str.Length)
                return self.Substring(0, self.Length - str.Length);
            else
                return self;
        }

        public static string PopFront(this string self, int count = 1)
        {
            if (count > self.Length || count < 0)
                throw new IndexOutOfRangeException();
            return self.Substring(count);
        }

        public static string PopBack(this string self, int count = 1)
        {
            if (count > self.Length || count < 0)
                throw new IndexOutOfRangeException();
            return self.Substring(0, self.Length - count);
        }
    }
}